package libnetdb.dm.assoc.dhp;
import libnetdb.dm.assoc.base.*;
import libnetdb.dm.assoc.util.*;

/**
 * <code>HashScannerBuilder</code> will build scanner which use a
 * hash tree structure to locates those candidates which may need
 * to be updated.
 *
 * @author Cheng-Ru Lin
 * @version 1.0
 */
public class HashScannerBuilder implements ScannerBuilder{
    private HashTable table;
    private int leaf_lmt, fanout, size = 0;

    /**
     * Constructs a new allocated <code>HashScannerBuilder</code>.
     * The hash tree built will has internal nodes and leaf nodes.
     * Each leaf nodes contains at most <code>leaf_limit</code>
     * candidates. And the fanout of an internal node is specified
     * by the parameter <code>fanout</code>.
     *
     * @param leaf_limit the limit of the number of candidates in
     *   a leaf node
     * @param fanout the fanout of an internal node
     */
    public HashScannerBuilder(int leaf_limit, int fanout) {
        this.leaf_lmt = leaf_limit;
        this.fanout = fanout;
        this.table = new HashTable(leaf_limit, fanout);
    }

    public void addCandidate(Litemset litemset){
        ++ size;
        table.addCandidate(litemset);
    }

    public Scanner getScanner(){
        if(size == 0) return null;
        table.congeal();
        Scanner scanner = new HashScanner(table);
        table = new HashTable(leaf_lmt, fanout);
        size = 0;
        return scanner;
    }

    static private class HashScanner extends AbstractScanner{
        private HashTable hash_table;
        private int tid = 0;
        public HashScanner(HashTable table){
            hash_table = table;
        }
        public void scan(Itemset tranx){
            hash_table.update(tid++, tranx.ids);
        }
    }

}